


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include <time.h>
//#include "config.h"
//#include "rtc_dev.h"
#include "print_log.h"

#include "risefall_time.h"




static double RAD = 180.0 * 3600 /M_PI;
static double midDayTime;
static double dawnTime;


/*************************
   
     * @param y 年
     *
     * @param M 月
     *
     * @param d 日
     *
     * @param h 时
     *
     * @param m 分
     *
     * @param s 秒
     *
     * @return int
***************************/
static double timeToDouble(int y, int M, double d)
{
//  double A=0;
    double B=0;
    double jd=0;
 
    B=-13;
    jd=floor(365.25 * (y + 4716))+ floor(30.60001 * (M + 1)) +B+ d- 1524.5;
    return jd;
}

/****************************
     * @param t 
     *
     * @return
*****************************/
static double sunHJ(double t)
{
        double j;
        t = t + (32.0 * (t + 1.8) * (t + 1.8) - 20) / 86400.0 / 36525.0;
        j = 48950621.66 + 6283319653.318 * t + 53 * t * t - 994 + 334166 *cos(4.669257 + 628.307585 * t) + 3489 * cos(4.6261 + 1256.61517 * t) + 2060.6 * cos(2.67823 + 628.307585 * t) * t;
        return (j / 10000000);
}

static double mod(double num1, double num2)
{
        num2 = fabs(num2);
        return num1 >= 0 ?(num1 - (floor(num1 / num2)) * num2 ): ((floor(fabs(num1) / num2)) * num2 - fabs(num1));
}
/********************************
     * (-p,p)
     *
     * @param ag
     * @return ag
***********************************/
static double degree(double ag)
{
        ag = mod(ag, 2 * M_PI);
        if(ag<=-M_PI){
            ag=ag+2*M_PI;
        }
        else if(ag>M_PI){
            ag=ag-2*M_PI;
        }
        return ag;
}


 static double sunRiseTime(double date, double lo, double la, double tz)
 {
        double t,j,sinJ,cosJ,gst,E,a,D,cosH0,cosH1,H0,H1,H;
        date = date - tz;
    
        t = date / 36525;
        j = sunHJ(t);
     
        sinJ = sin(j);
        cosJ = cos(j);
   
        gst = 2 * M_PI * (0.779057273264 + 1.00273781191135 * date) + (0.014506 + 4612.15739966 * t + 1.39667721 * t * t) / RAD;
        E = (84381.406 - 46.836769 * t) / RAD; 
        a = atan2(sinJ * cos(E), cosJ);
        D = asin(sin(E) * sinJ); 
        cosH0 = (sin(-50 * 60 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); 
        cosH1 = (sin(-6 * 3600 / RAD) - sin(la) * sin(D)) / (cos(la) * cos(D)); 
    
        if (cosH0 >= 1 || cosH0 <= -1){
            return -0.5;
        }
        H0 = -acos(cosH0); 
        H1 = -acos(cosH1);
        H = gst - lo - a;
        midDayTime = date - degree(H) / M_PI / 2 + tz;      
        dawnTime = date - degree(H - H1) / M_PI / 2 + tz;   
        return date - degree(H - H0) / M_PI / 2 + tz;       
}




static void time_shift(const double *pin_time, OUT Time_HMS_st *pTime)
{
	double t;

	t = *pin_time + 0.5;
	t = (t - (int) t) * 24;
	pTime->ucHour = (int) t;
	t = (t - pTime->ucHour) * 60;
	pTime->ucMinute = (int) t;
	t = (t - pTime->ucMinute) * 60;
	pTime->ucSecond = (int) t;
  
}

static int  calc_time_riseall(const time_calc_pa_t *param, OUT ScmSunTime *pSuntime)
{
    int year;
    int month;
    double day;
    int hour;
    int min;
    int sec;
    int i;

    int tz = param->tz;  //  8;
    double jd = -(param->jd)/180*M_PI;
    double wd = (param->wd)/180*M_PI;
    year = param->ds_time.ucYear+2000;
    month = param->ds_time.ucMonth;
    day = param->ds_time.ucDate;
    hour = 17;
    min = 9;
    sec = 0;
    
    double richu = timeToDouble(year,month,day) - 2451544.5;
    for (i = 0; i < 10; i++){
        richu = sunRiseTime(richu, jd, wd, tz/24.0);
    }
    dawnTime=midDayTime + midDayTime - richu;
	
    pSuntime->d_SunRise = richu;
    pSuntime->d_SunDown = dawnTime;
	
    return 0;

}



/**
get_sun_risefall_time() ：算日出日落时间
param:  lng,  经度
        lat,  纬度
        tz,   时区
        p_risefall_time :  返回 日出日落时间结构体
**/
int get_sun_risefall_time(unsigned int lng, unsigned int lat, unsigned int tz, RTC_Data_st* rtc_now, OUT Time_HMS_st *p_rise, OUT Time_HMS_st *p_fall )
{

	//log_debug("lng=%d, lat=%d, tz=%d", lng, lat, tz);
	
	time_calc_pa_t time_calc_param={0};
	time_calc_param.jd = ((double)lng)/100;
	time_calc_param.wd = ((double)lat)/100;
	time_calc_param.tz = tz;
	
	//log_debug("jd=%f, wd=%f", time_calc_param.jd, time_calc_param.wd);
		

#if 0	
	struct tm  *local;
	struct timeval tv;
	gettimeofday(&tv,NULL);
	local = localtime(&tv.tv_sec);
	time_calc_param.ds_time.ucDate = local->tm_mday;
	time_calc_param.ds_time.ucMonth = local->tm_mon + 1;
	time_calc_param.ds_time.ucYear = local->tm_year - 100;
#endif

	time_calc_param.ds_time.ucDate  = rtc_now->ucDate;
	time_calc_param.ds_time.ucMonth = rtc_now->ucMonth;
	time_calc_param.ds_time.ucYear  = rtc_now->ucYear;


	ScmSunTime sun_time;

	//sun_time = TimeCalculation(jd_degrees, wd_degrees, tz, DS3231time);
	calc_time_riseall(&time_calc_param, &sun_time);

	time_shift(&sun_time.d_SunRise, p_rise);
	time_shift(&sun_time.d_SunDown, p_fall);


#if 0
	log_debug("riseTime = %02d:%02d\n", p_rise->ucHour,  p_rise->ucMinute);
	log_debug("fallTime = %02d:%02d\n", p_fall->ucHour, p_fall->ucMinute);

	//riseTime = 06:08fallTime = 18:15riseTime = 06:08fallTime = 18:15riseTime = 06:08f
	
#endif

	return 0;	

}












